package chalmers.game.subterranean.model.player;

import chalmers.game.subterranean.event.Bus;
import chalmers.game.subterranean.event.events.player.JumpEvent;
import chalmers.game.subterranean.event.events.player.MoveOnGroundEvent;
import chalmers.game.subterranean.model.physics.IMovableBody;
import chalmers.game.subterranean.util.Direction;
import chalmers.game.subterranean.util.options.Speeds;
import lombok.Setter;
import org.apache.log4j.Logger;

/**
 * A player state that handles actions of the player whe she is standing on solid ground.
 * 
 * @author Alex Evert
 */
public class StateGround implements IState {

  /**
   * The logger used for reporting significant events.
   */
  private static final Logger logger = Logger.getLogger("subLog");



  /**
   * The player that the context belongs to, used to set properties shared between states.
   */
  private @Setter
  PlayerContext player;


  /**
   * Give the player a boost to the upwards velocity and change the state to airbourne.
   */
  @Override
  public void jump(IMovableBody body) {
    body.setYVelocity(Speeds.JUMPSPEED);
    player.setStateAir();
    logger.info("Player jumped.");
    Bus.INSTANCE.post(new JumpEvent());
  }

  /**
   * Run in given direction. Since the player has solid ground under her feets she can run at full
   * speed.
   * 
   * @param body
   * @param direction The direction the player should run towards.
   */
  @Override
  public void run(IMovableBody body, Direction direction) {
    if (direction == Direction.EAST) {
      body.setXVelocity(Speeds.RUNSPEED);
      logger.info("The player runs eastwards.");
    } else if (direction == Direction.WEST) {
      body.setXVelocity(-Speeds.RUNSPEED);
      logger.info("The player runs westwards.");
    }

  }

  /**
   * Stop the player. Solid ground gives the ability to stop on a dime.
   */
  @Override
  public void stop(IMovableBody body) {
    body.setXVelocity(0);
    logger.info("The player stopped.");
  }

  @Override
  public void bounce(IMovableBody body, Direction direction) {
    body.setXVelocity(0);
    logger.info("The player bounced while standing on ground.");
  }

  @Override
  public void checkSurrounding(IMovableBody body) {
    if (body.findFreeSpace(Direction.SOUTH)) {
      player.setStateAir();
      logger.info("The player fell.");
    } else if (body.getXVelocity() != 0) {
      // TODO: Fix this uggly hack. plays sound if
      // player is on ground and moves. /Alex
      Bus.INSTANCE.post(new MoveOnGroundEvent());
    }
  }
}
